package org.jeecg.modules.rental.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.rental.vo.LoginRentalAccount;
import org.jeecg.modules.iot.api.IControlAPI;
import org.jeecg.modules.rental.entity.RentalAccount;
import org.jeecg.modules.rental.entity.RentalAccountPackage;
import org.jeecg.modules.rental.entity.RentalEBike;
import org.jeecg.modules.rental.entity.RentalOrder;
import org.jeecg.modules.rental.enums.DepositStatusEnums;
import org.jeecg.modules.rental.enums.EBikeOrderTypeEnums;
import org.jeecg.modules.rental.enums.EBikeRentalVerifyEnums;
import org.jeecg.modules.rental.mapper.RentalAccountMapper;
import org.jeecg.modules.rental.mapper.RentalAccountPackageMapper;
import org.jeecg.modules.rental.mapper.RentalEBikeMapper;
import org.jeecg.modules.rental.mapper.RentalOrderMapper;
import org.jeecg.modules.rental.req.BindPackageReq;
import org.jeecg.modules.rental.service.IRentalAccountPackageService;
import org.jeecg.modules.rental.service.IRentalEBikeService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 账户(客户)套餐
 * @Author: sean
 * @Date:   2024-06-17
 * @Version: V1.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RentalAccountPackageServiceImpl extends ServiceImpl<RentalAccountPackageMapper, RentalAccountPackage> implements IRentalAccountPackageService {

    private final RentalOrderMapper rentalOrderMapper;

    private final RentalAccountMapper rentalAccountMapper;

    private final RentalEBikeMapper rentalEBikeMapper;

    private final IRentalEBikeService rentalEBikeService;

    private final IControlAPI iControlAPI;

//    @Autowired
//    private PaymentServiceFactory paymentServiceFactory;

    @Override
    public IPage<RentalAccountPackage> selectJoinPage(Page page, Wrapper wrapper) {
        Page<RentalAccountPackage> pageList = baseMapper.selectJoinPage(page, wrapper);
        if(ObjectUtil.isNotEmpty(pageList) && ObjectUtil.isNotEmpty(pageList.getRecords())){
            List<Long> packageIds = pageList.getRecords().stream().map(RentalAccountPackage::getId).collect(Collectors.toList());
            List<String> accountIds = pageList.getRecords().stream().map(RentalAccountPackage::getAccountId).collect(Collectors.toList());
            List<Long> carIds = pageList.getRecords().stream().map(RentalAccountPackage::getCarId).collect(Collectors.toList());

            List<RentalOrder> orderList = rentalOrderMapper.selectList(new QueryWrapper<RentalOrder>().in("account_package_id", packageIds));
            List<RentalAccount> payAccountList = rentalAccountMapper.selectBatchIds(accountIds);
            List<RentalEBike> carList = rentalEBikeMapper.selectBatchIds(carIds);

            pageList.getRecords().stream().forEach(item-> {
                RentalAccount rentalPayAccount = payAccountList.stream()
                        .filter(a-> a.getId().toString().equals(item.getAccountId())).findFirst().orElse(null);
                if(ObjectUtil.isNotEmpty(rentalPayAccount)){
                    item.setAccountPhone(rentalPayAccount.getAccountCode()); // 如果手机号长度不足 7 位，则直接显示
//                    String phone = rentalPayAccount.getPhone();
//                    if (phone != null && phone.length() >= 7) {
//                        item.setAccountPhone(phone.substring(0, 3) + "****" + phone.substring(phone.length() - 4));
//                    } else {
//                        item.setAccountPhone(phone); // 如果手机号长度不足 7 位，则直接显示
//                    }
                }

                RentalEBike rentalCar = carList.stream()
                        .filter(a-> a.getId().equals(item.getCarId())).findFirst().orElse(null);
                if(ObjectUtil.isNotEmpty(rentalCar)){
                    item.setCarPlate(rentalCar.getPlate());
                }

                RentalOrder rentalOrder = orderList.stream()
                        .filter(a-> a.getAccountPackageId().equals(item.getId()) && a.getOrderType().equals(1)
                                && a.getOrderStatus().equals(2) ).findFirst().orElse(null);
                if(ObjectUtil.isNotEmpty(rentalOrder)){
                    item.setDepositAmount(rentalOrder.getDepositAmount());
                    item.setPackageAmount(rentalOrder.getOrderAmount().subtract(rentalOrder.getDepositAmount()));
                }

                RentalOrder rentalOrder2 = orderList.stream()
                        .filter(a-> a.getAccountPackageId().equals(item.getId()) && a.getOrderType().equals(3)
                                && a.getOrderStatus().equals(2) ).findFirst().orElse(null);
                if(ObjectUtil.isNotEmpty(rentalOrder2)){
                    item.setTimeoutAmount(rentalOrder2.getOrderAmount());
                }
            });
        }
        return pageList;
    }

    @Override
    public Result<String> verifyPackage(String accountPackageId) {
        RentalAccountPackage accountPackage=baseMapper.selectById(accountPackageId);

        LocalDateTime now=LocalDateTime.now();
        if (now.isBefore(accountPackage.getStartTime()) || now.isAfter(accountPackage.getEndTime())) {
            if (now.isAfter(accountPackage.getEndTime())){
                if ("2".equals(accountPackage.getPkgCategory())&&accountPackage.getCarId()==null){
                    accountPackage.setPkgStatus("2");
                }else if ("1".equals(accountPackage.getPkgCategory())){
                    accountPackage.setPkgStatus("2");
                }
                baseMapper.updateById(accountPackage);
                return new Result(EBikeRentalVerifyEnums.PACKAGE_TIMEOUT.getCode(),EBikeRentalVerifyEnums.PACKAGE_TIMEOUT.getMessage());
            }else if (now.isBefore(accountPackage.getStartTime())){
                return new Result(EBikeRentalVerifyEnums.PACKAGE_NOT_EFFECTIVE.getCode(),EBikeRentalVerifyEnums.PACKAGE_NOT_EFFECTIVE.getMessage());

            }
        }
        return Result.OK();

    }

//    @Override
//    public Result<Boolean> refund(AccountPackageReq req) throws Exception {
////        IPaymentService paymentService = paymentServiceFactory.getPaymentService(OrgThreadHolder.get());
//        RentalAccountPackage accountPackage=new RentalAccountPackage();
//        accountPackage=baseMapper.selectById(req.getAccountPackageId());
//        if (accountPackage!=null){
//            //TODO 退款
////            return paymentService.allRefund(accountPackage);
//            return Result.OK(false);
//        }else {
//            return Result.error("rentalpayaccount.service.package.not.found");
//        }
//    }

    @Override
    public RentalAccountPackage curPkgByCarId(Long carId) {
        QueryWrapper queryWrapper = new QueryWrapper<RentalAccountPackage>();
        queryWrapper.eq("car_id", carId);
        queryWrapper.eq("pkg_status","1");
        return baseMapper.curPkgByCarId(queryWrapper);
    }

    @Override
    public RentalAccountPackage getCurrentUserAccountPackage() {
        return null;
    }

    @Override
    public Result bindEBike(BindPackageReq req) {
        LocalDateTime now=LocalDateTime.now();
        RentalAccountPackage rentalAccountPackage= baseMapper.selectById(req.getAccountPackageId());
        // 判断当前时间是否在套餐有效期内
        if (now.isBefore(rentalAccountPackage.getStartTime()) || now.isAfter(rentalAccountPackage.getEndTime())) {
            throw new JeecgBootException("rentalcarpackage.service.package.expired.or.not.effective");
        }
        //TODO 校验车子
        Result<RentalEBike> rentalEBikeResult =  rentalEBikeService.newVerify(req.getCode(), true);
        if(rentalEBikeResult.isSuccess() && 0 == rentalEBikeResult.getCode()){
            RentalEBike rentalEBike = rentalEBikeResult.getResult();
            iControlAPI.openCar(rentalEBike.getCarCode(), rentalEBike.getPhone());
            rentalAccountPackage.setCarId(rentalEBike.getId());
            return Result.ok(baseMapper.updateById(rentalAccountPackage) > 0);
        }
        return rentalEBikeResult;
    }


    @Override
    public List<RentalAccountPackage> effectivePackages() {
        LoginRentalAccount loginRentalAccount = (LoginRentalAccount) SecurityUtils.getSubject().getPrincipal();
        QueryWrapper queryWrapper = new QueryWrapper<RentalAccountPackage>();
        queryWrapper.eq("account_id", loginRentalAccount.getId());
        queryWrapper.eq("pkg_status","1");
        return baseMapper.effectivePackages(queryWrapper);
    }

    @Override
    public Page<RentalAccountPackage> historyPackages(Page page) {
        LoginRentalAccount rentalAccount = (LoginRentalAccount) SecurityUtils.getSubject().getPrincipal();
        QueryWrapper<RentalAccountPackage> queryWrapper = new QueryWrapper<RentalAccountPackage>();
        queryWrapper.eq("account_id", rentalAccount.getId());
        queryWrapper.orderByDesc("create_time");
        Page<RentalAccountPackage> accountPackagePage = baseMapper.selectPage(page, queryWrapper);
        if(ObjectUtil.isNotEmpty(accountPackagePage.getRecords()) ){
            List<Long> carIds = accountPackagePage.getRecords().stream().map(RentalAccountPackage::getCarId).collect(Collectors.toList());
            List<RentalEBike> carList = rentalEBikeService.listWithType(carIds);

            List<Long> accountPackageIdList = accountPackagePage.getRecords().stream()
                    .map(RentalAccountPackage::getId).collect(Collectors.toList());
            List<RentalOrder> orderList = rentalOrderMapper.selectList(new QueryWrapper<RentalOrder>().ne("order_type", EBikeOrderTypeEnums.RENEW_ORDER.getValue())
                    .in("account_package_id", accountPackageIdList));
            accountPackagePage.getRecords().forEach(item->{
                RentalEBike rentalCar = carList.stream().filter(a-> a.getId().equals(item.getCarId())).findFirst().orElse(null);
                if(ObjectUtil.isNotEmpty(rentalCar)){
                    item.setCarImage(rentalCar.getCarTypeImage());
                }
                RentalOrder rentalOrder = orderList.stream()
                        .filter(a-> a.getAccountPackageId().equals(item.getId())).findFirst().orElse(null);
                if(ObjectUtil.isNotEmpty(rentalOrder)){
                    item.setDepositAmount(rentalOrder.getDepositAmount());
                }else{
                    item.setDepositAmount(BigDecimal.ZERO);
                }
                item.setDepositStatusStr(DepositStatusEnums.getEnumByValue(item.getDepositStatus().toString()).getLabel());
            });
        }
        return accountPackagePage;
    }


}
